package com.ibiaoke.order.dao;

import com.ibiaoke.common.base.BaseDao;
import com.ibiaoke.common.base.Page;
import com.ibiaoke.common.consts.CommonConsts;
import com.ibiaoke.common.utils.AssertUtils;
import com.ibiaoke.common.utils.DateUtils;
import com.ibiaoke.order.consts.OrderStatusConst;
import com.ibiaoke.order.entity.Order;
import com.ibiaoke.order.entity.OrderExample;
import com.ibiaoke.order.entity.so.OrderSO;
import com.ibiaoke.order.mapper.OrderMapper;
import org.apache.commons.lang.StringUtils;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by huhaichao on 2017/6/8.
 */
@Repository
public class OrderDao extends BaseDao<Order, OrderExample, Integer, OrderMapper> {

    @Autowired
    private OrderMapper orderMapper;


    @Override
    public OrderMapper getMapper() {
        return orderMapper;
    }

    /**
     * 查询订单列表
     *
     * @param orderSO
     * @param page
     * @return
     */
    public List<Order> listOrder(OrderSO orderSO, Page page) {
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        if (StringUtils.isNotBlank(orderSO.getOrderCode())) {
            criteria.andOrderCodeLike("%" + orderSO.getOrderCode() + "%");
        }
        if (orderSO.getOrderStatus() != null) {
            //待收货
            if (orderSO.getOrderStatus() == -1) {
                criteria.andOrderStatusIn(Arrays.asList(OrderStatusConst.PAID ,OrderStatusConst.DELIVERED));
            }else {
                criteria.andOrderStatusEqualTo(orderSO.getOrderStatus());
            }
        }
        /*if (StringUtils.isNotBlank(orderSO.getMobile())) {
            criteria.andContactMobileEqualTo(orderSO.getMobile());
        }*/
        if (orderSO.getBeginTime() != null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(orderSO.getBeginTime());
        }
        if (orderSO.getEndTime() != null) {
            criteria.andCreateTimeLessThan(orderSO.getEndTime());
        }
        if (orderSO.getUserId() != null) {
            criteria.andUserIdEqualTo(orderSO.getUserId());
        }
        if (orderSO.getShopId() != null) {
            criteria.andShopIdEqualTo(orderSO.getShopId());
        }

        if (orderSO.getSource() != null) {
            criteria.andSourceEqualTo(orderSO.getSource());
        }
        if (orderSO.getDeliveryType() != null) {
            criteria.andDeliveryTypeEqualTo(orderSO.getDeliveryType());
        }
        if (orderSO.isDateAnalysis() == true) {
            criteria.andOrderStatusIn(Arrays.asList(OrderStatusConst.PAID, OrderStatusConst.DELIVERED, OrderStatusConst.RECEIVED));
        }
        if (page != null) {
            page.setTotalCount(orderMapper.countByExample(orderExample));
            orderExample.setLimitStart(page.limitStart());
            orderExample.setLimitEnd(page.limitEnd());
        }
        orderExample.setOrderByClause("create_time desc ");
        return orderMapper.selectByExample(orderExample);
    }

    /**
     * 更新订单状态
     *
     * @param orderId 订单id
     * @param status  订单状态
     */
    public int updateOrderStatus(int orderId, int status) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setOrderStatus(status);
        return orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 根据订单号查询订单
     *
     * @param orderCode
     * @return
     */
    public Order getOrderByOrderCode(String orderCode) {
        OrderExample example = new OrderExample();
        example.createCriteria().andOrderCodeEqualTo(orderCode);
        return getByExample(example);
    }

    /**
     * 订单数量查询
     *
     * @param customerId
     * @param orderStatus
     * @return
     */
    public Long countOrder(Integer customerId, int orderStatus) {
        OrderExample example = new OrderExample();
        OrderExample.Criteria criteria = example.createCriteria().andOrderStatusEqualTo(orderStatus).andUserIdEqualTo(customerId).andDeliveryTypeEqualTo(0);
        if(Objects.equals(orderStatus,OrderStatusConst.UNPAID)){
            criteria.andCreateTimeGreaterThan(DateUtils.add(Calendar.HOUR,-1));
        }
        return orderMapper.countByExample(example);
    }

    /**
     * 取消订单
     *
     * @param customerId
     * @param orderId
     * @return
     */
    public Integer cancelOrder(Integer customerId, Integer orderId) {
        OrderExample example = new OrderExample();
        example.createCriteria().andUserIdEqualTo(customerId).andOrderIdEqualTo(orderId);
        Order order = new Order();
        order.setOrderStatus(OrderStatusConst.CANCELED);
        return orderMapper.updateByExampleSelective(order, example);
    }

    public int confirmOrder(Integer customerId, Integer orderId) {
        OrderExample example = new OrderExample();
        example.createCriteria().andUserIdEqualTo(customerId).andOrderIdEqualTo(orderId).andOrderStatusIn(Arrays.asList(OrderStatusConst.PAID, OrderStatusConst.DELIVERED));
        Order order = new Order();
        order.setOrderStatus(OrderStatusConst.RECEIVED);
        return orderMapper.updateByExampleSelective(order, example);
    }

    public int payOrder(Integer orderId, Integer payType) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setOrderStatus(OrderStatusConst.PAID);
        order.setPayType(payType);
        order.setPayTime(new Date());
        return updateByPrimaryKeySelective(order);
    }

    public int countOrderGoods(int userId, int goodsId, Date beginTime, Date endTime) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("goodsId", goodsId);
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);
        Integer count = orderMapper.countOrderGoods(map);
        return count == null ? 0 : count;
    }

    public void updateOrderShop(Integer orderId, Integer shopId) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setShopId(shopId);
        updateByPrimaryKeySelective(order);
    }

    public int useCoupon(Integer orderId, Integer couponReceiveId, BigDecimal newPrice, BigDecimal couponPrice) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setCouponReceiveId(couponReceiveId);
        order.setOrderPrice(newPrice);
        order.setCouponPrice(couponPrice);
        return updateByPrimaryKeySelective(order);
    }

    public int changeOrderNo(Integer orderId, String orderNo) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setOrderCode(orderNo);
        return updateByPrimaryKeySelective(order);
    }

    public int confirmOrder(Date time) {
        OrderExample example = new OrderExample();
        example.createCriteria().andOrderStatusIn(Arrays.asList(OrderStatusConst.PAID, OrderStatusConst.DELIVERED))
                .andPayTimeLessThan(time);
        Order order = new Order();
        order.setOrderStatus(OrderStatusConst.RECEIVED);
        return updateByExampleSelective(order, example);
    }

    public int cancelOrder(Date time) {
        OrderExample example = new OrderExample();
        example.createCriteria().andOrderStatusEqualTo(OrderStatusConst.UNPAID).andCreateTimeLessThan(time);
        Order order = new Order();
        order.setOrderStatus(OrderStatusConst.CANCELED);
        return updateByExampleSelective(order, example);
    }

    public List<Order> listCancelOrder(Date time) {
        OrderExample example = new OrderExample();
        example.createCriteria().andOrderStatusEqualTo(OrderStatusConst.UNPAID).andCreateTimeLessThan(time);
        return selectByExample(example);
    }


    public List<Order> listShopOrder(Integer shopId, Date begin, Date end) {
        AssertUtils.notNull(shopId,"店铺Id不能为空");
        OrderExample example = new OrderExample();
        example.createCriteria().andShopIdEqualTo(shopId).andPayTimeBetween(begin, end);
        return orderMapper.selectByExample(example);
    }

    public List<Order> aggregate(Integer serviceNum, Date startTime, Date endTime) {
        OrderExample example = new OrderExample();
        example.createCriteria()
                .andServiceNumEqualTo(serviceNum)
                .andCreateTimeGreaterThanOrEqualTo(startTime)
                .andCreateTimeLessThan(endTime);
        return orderMapper.selectByExample(example);
    }
}
